package com.demo.app.activiti.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.demo.app.file.mapper.LeaveMapper;
import model.leave.Leave;
import model.leave.LeaveRecord;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import result.Result;

import javax.annotation.Resource;
import java.util.*;

/**
 * @program: couple-game
 * @description:
 * @author: fbl
 * @create: 2025-04-11 09:46
 **/
@Component
public class ActivitiService {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;

    @Resource
    LeaveMapper leaveMapper;

    private final String key = "leave2";


    public Result deployment() {
         repositoryService.createDeployment()
                .addClasspathResource("processes/leave2.bpmn20.xml")
                .category(key)
                .name("请假流程（加强版）")
                .key(key)
                .deploy();
        return Result.success();
    }

    public Result applyLeave(String applyUserId){
        String businessKey = UUID.randomUUID().toString();
        // 启动请假流程
        Map<String, Object> applyUserMap = new HashMap<>();
        /*  设置申请用户id */
        applyUserMap.put("applyUser", applyUserId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key, businessKey, applyUserMap);
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        String taskId = task.getId();

        HashMap<String, String> map = new HashMap<>();
        map.put("taskId", taskId);
        map.put("businessKey", businessKey);
        return Result.success(map);
    }

    @Transactional(rollbackFor = Exception.class)
    public Result applySubmit(Leave leave){
        // 置入业务信息
        leaveMapper.insert(leave);
        String taskId = leave.getTaskId();
        // 设置下一节点hrs审核（模仿查询hr角色的用户id）5
        Map<String, Object> hrsMap = new HashMap<>();
        hrsMap.put("hrs", "1,2,3");
        taskService.complete(taskId,hrsMap);
        return Result.success();
    }

    public Result applyLeaveList(String applyUserId) {
        List<Task> taskList = taskService.createTaskQuery()
                .taskAssignee(applyUserId)
                .list();
        ArrayList<LeaveRecord> leaveRecords = new ArrayList<>();
        LeaveRecord leaveRecord;
        for (Task task : taskList) {
            leaveRecord = new LeaveRecord();
            String businessKey = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(task.getProcessInstanceId())
                    .singleResult()
                    .getBusinessKey();
            LambdaQueryWrapper<Leave> leaveLambdaQueryWrapper = new LambdaQueryWrapper<Leave>().eq(Leave::getBusinessKey, businessKey);
            List<Leave> leaves = leaveMapper.selectList(leaveLambdaQueryWrapper);
            leaves.forEach(e -> e.setTaskId(task.getId()));
            leaveRecord.setBusinessKey(businessKey);
            leaveRecord.setLeaves(leaves);
            leaveRecord.setTaskId(task.getId());
            leaveRecords.add(leaveRecord);
        }
        return Result.success(leaveRecords);
    }

    public Result hrAuditList(String hrUserId) {
        List<Task> list =
                taskService.createTaskQuery()
                        .taskCandidateUser(hrUserId)
                        .list();
        ArrayList<LeaveRecord> leaveRecords = new ArrayList<>();
        LeaveRecord leaveRecord;
        for (Task task : list) {
            leaveRecord = new LeaveRecord();
            ProcessInstance execution = (ProcessInstance)runtimeService.createExecutionQuery().executionId(task.getProcessInstanceId()).singleResult();
            String businessKey = execution.getBusinessKey();
            LambdaQueryWrapper<Leave> leaveLambdaQueryWrapper = new LambdaQueryWrapper<Leave>().eq(Leave::getBusinessKey, businessKey);
            List<Leave> leaves = leaveMapper.selectList(leaveLambdaQueryWrapper);
            leaves.forEach(e -> e.setTaskId(task.getId()));
            leaveRecord.setBusinessKey(businessKey);
            leaveRecord.setLeaves(leaves);
            leaveRecord.setTaskId(task.getId());
            leaveRecords.add(leaveRecord);
        }
        return Result.success(leaveRecords);
    }

    public Result hrAudit(Leave leave) {
        // 更新请假表 hr意见
        leaveMapper.updateById(leave);
        // 组任务拾取变成个人任务
        taskService.claim(leave.getTaskId(), leave.getHrUserId());
        // 审核是否通过，决定下一走向
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("result", leave.getResult());
        // hr审核通过，设置bossUserId
        if(leave.getResult() == 1){
            resultMap.put("boss", "999");
        }
        taskService.complete(leave.getTaskId(),resultMap);
        return Result.success();
    }

    public Result bossAuditList(String bossUserId) {
        List<Task> list =
                taskService.createTaskQuery()
                        .taskAssignee(bossUserId)
                        .list();
        ArrayList<LeaveRecord> leaveRecords = new ArrayList<>();
        LeaveRecord leaveRecord;
        for (Task task : list) {
            leaveRecord = new LeaveRecord();
            ProcessInstance execution = (ProcessInstance)runtimeService.createExecutionQuery().executionId(task.getProcessInstanceId()).singleResult();
            String businessKey = execution.getBusinessKey();
            LambdaQueryWrapper<Leave> leaveLambdaQueryWrapper = new LambdaQueryWrapper<Leave>().eq(Leave::getBusinessKey, businessKey);
            List<Leave> leaves = leaveMapper.selectList(leaveLambdaQueryWrapper);
            leaves.forEach(e -> e.setTaskId(task.getId()));
            leaveRecord.setBusinessKey(businessKey);
            leaveRecord.setLeaves(leaves);
            leaveRecord.setTaskId(task.getId());
            leaveRecords.add(leaveRecord);
        }
        return Result.success(leaveRecords);
    }

    public Result bossAudit(Leave leave) {
        // 更新请假表 boss意见
        leaveMapper.updateById(leave);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("result", leave.getResult());
        taskService.complete(leave.getTaskId(),resultMap);
        return Result.success();
    }

    public Result record() {
        List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
                .processDefinitionKey(key)
                .list();
        HashMap<String, List<Leave>> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (HistoricProcessInstance historicProcessInstance : list) {
                LambdaQueryWrapper<Leave> leaveLambdaQueryWrapper = new LambdaQueryWrapper<Leave>().eq(Leave::getBusinessKey, historicProcessInstance.getBusinessKey());
                List<Leave> leaves = leaveMapper.selectList(leaveLambdaQueryWrapper);
                map.put(historicProcessInstance.getBusinessKey(), leaves);
            }
        }
        return Result.success(map);
    }

}
